home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / system-config-printer / troubleshoot / __init__.py next >
Encoding:
Python Source  |  2009-05-05  |  11.7 KB  |  378 lines

  1. #!/usr/bin/env python
  2.  
  3. ## Printing troubleshooter
  4.  
  5. ## Copyright (C) 2008 Red Hat, Inc.
  6. ## Copyright (C) 2008 Tim Waugh <twaugh@redhat.com>
  7.  
  8. ## This program is free software; you can redistribute it and/or modify
  9. ## it under the terms of the GNU General Public License as published by
  10. ## the Free Software Foundation; either version 2 of the License, or
  11. ## (at your option) any later version.
  12.  
  13. ## This program is distributed in the hope that it will be useful,
  14. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. ## GNU General Public License for more details.
  17.  
  18. ## You should have received a copy of the GNU General Public License
  19. ## along with this program; if not, write to the Free Software
  20. ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. import gtk
  23. import pprint
  24. import sys
  25. import traceback
  26.  
  27. if __name__ == "__main__":
  28.     import os.path
  29.     import gettext
  30.     gettext.textdomain ('system-config-printer')
  31.  
  32.     if sys.argv[0][0] != '/':
  33.         cwd = os.getcwd ()
  34.         path = cwd + os.path.sep + sys.argv[0]
  35.     else:
  36.         path = sys.argv[0]
  37.     sub = os.path.dirname (path)
  38.     root = os.path.dirname (sub)
  39.     sys.path.append (root)
  40.  
  41. import base
  42. from base import *
  43.  
  44. class Troubleshooter:
  45.     def __init__ (self, quitfn=None, parent=None):
  46.         self._in_module_call = False
  47.  
  48.         main = gtk.Window ()
  49.         if parent:
  50.             main.set_transient_for (parent)
  51.             main.set_position (gtk.WIN_POS_CENTER_ON_PARENT)
  52.             main.set_modal (True)
  53.  
  54.         main.set_title (_("Printing troubleshooter"))
  55.         main.set_property ("default-width", 400)
  56.         main.set_property ("default-height", 350)
  57.         main.connect ("delete_event", self.quit)
  58.         self.main = main
  59.         self.quitfn = quitfn
  60.  
  61.         vbox = gtk.VBox ()
  62.         main.add (vbox)
  63.         ntbk = gtk.Notebook ()
  64.         ntbk.set_border_width (6)
  65.         vbox.pack_start (ntbk, True, True, 0)
  66.         vbox.pack_start (gtk.HSeparator (), False, False, 0)
  67.         box = gtk.HButtonBox ()
  68.         box.set_border_width (6)
  69.         box.set_spacing (3)
  70.         box.set_layout (gtk.BUTTONBOX_END)
  71.  
  72.         back = gtk.Button (stock='gtk-go-back')
  73.         back.connect ('clicked', self._on_back_clicked)
  74.         back.set_sensitive (False)
  75.         self.back = back
  76.  
  77.         close = gtk.Button (stock='gtk-close')
  78.         close.connect ('clicked', self.quit)
  79.         self.close = close
  80.  
  81.         cancel = gtk.Button (stock='gtk-cancel')
  82.         cancel.connect ('clicked', self.quit)
  83.         self.cancel = cancel
  84.  
  85.         forward = gtk.Button (stock='gtk-go-forward')
  86.         forward.connect ('clicked', self._on_forward_clicked)
  87.         forward.set_flags (gtk.CAN_DEFAULT | gtk.HAS_DEFAULT)
  88.         self.forward = forward
  89.  
  90.         box.pack_start (back, False, False, 0)
  91.         box.pack_start (cancel, False, False, 0)
  92.         box.pack_start (close, False, False, 0)
  93.         box.pack_start (forward, False, False, 0)
  94.         vbox.pack_start (box, False, False, 0)
  95.  
  96.         ntbk.set_current_page (0)
  97.         ntbk.set_show_tabs (False)
  98.         self.ntbk = ntbk
  99.         self.current_page = 0
  100.  
  101.         self.questions = []
  102.         self.question_answers = []
  103.         self.answers = {}
  104.         self.moving_backwards = False
  105.  
  106.         main.show_all ()
  107.  
  108.     def quit (self, *args):
  109.         if self._in_module_call:
  110.             try:
  111.                 self.questions[self.current_page].cancel_operation ()
  112.             except:
  113.                 self._report_traceback ()
  114.  
  115.             return
  116.  
  117.         try:
  118.             self.questions[self.current_page].disconnect_signals ()
  119.         except:
  120.             self._report_traceback ()
  121.  
  122.         # Delete the questions so that their __del__ hooks can run.
  123.         # Do this in reverse order of creation.
  124.         for i in xrange (len (self.questions)):
  125.             self.questions.pop ()
  126.  
  127.         self.main.hide ()
  128.         if self.quitfn:
  129.             self.quitfn (self)
  130.  
  131.     def get_window (self):
  132.         # Any error dialogs etc from the modules need to be able
  133.         # to set themselves transient for this window.
  134.         return self.main
  135.  
  136.     def no_more_questions (self, question):
  137.         page = self.questions.index (question)
  138.         debugprint ("Page %d: No more questions." % page)
  139.         self.questions = self.questions[:page + 1]
  140.         self.question_answers = self.question_answers[:page + 1]
  141.         for p in range (self.ntbk.get_n_pages () - 1, page, -1):
  142.             self.ntbk.remove_page (p)
  143.         self._set_back_forward_buttons ()
  144.  
  145.     def new_page (self, widget, question):
  146.         page = len (self.questions)
  147.         debugprint ("Page %d: new: %s" % (page, str (question)))
  148.         self.questions.append (question)
  149.         self.question_answers.append ([])
  150.         self.ntbk.insert_page (widget, position=page)
  151.         widget.show_all ()
  152.         if page == 0:
  153.             try:
  154.                 question.connect_signals (self._set_back_forward_buttons)
  155.             except:
  156.                 self._report_traceback ()
  157.  
  158.             self.ntbk.set_current_page (page)
  159.             self.current_page = page
  160.         self._set_back_forward_buttons ()
  161.         return page
  162.  
  163.     def is_moving_backwards (self):
  164.         return self.moving_backwards
  165.  
  166.     def answers_as_text (self):
  167.         text = ""
  168.         n = 1
  169.         for i in range (self.current_page):
  170.             answers = self.question_answers[i].copy ()
  171.             for hidden in filter (lambda x: x.startswith ("_"), answers.keys()):
  172.                 del answers[hidden]
  173.             if len (answers.keys ()) == 0:
  174.                 continue
  175.             text += "Page %d (%s):" % (n, self.questions[i]) + '\n'
  176.             text += pprint.pformat (answers) + '\n'
  177.             n += 1
  178.         return text.rstrip () + '\n'
  179.  
  180.     def busy (self):
  181.         self.forward.set_sensitive (False)
  182.         self.back.set_sensitive (False)
  183.         gdkwin = self.get_window ().window
  184.         if gdkwin:
  185.             gdkwin.set_cursor (gtk.gdk.Cursor (gtk.gdk.WATCH))
  186.             while gtk.events_pending ():
  187.                 gtk.main_iteration ()
  188.  
  189.     def ready (self):
  190.         gdkwin = self.get_window ().window
  191.         if gdkwin:
  192.             gdkwin.set_cursor (gtk.gdk.Cursor (gtk.gdk.LEFT_PTR))
  193.  
  194.         self._set_back_forward_buttons ()
  195.  
  196.     def _set_back_forward_buttons (self, *args):
  197.         page = self.current_page
  198.         self.back.set_sensitive (page != 0)
  199.         if len (self.questions) == page + 1:
  200.             # Out of questions.
  201.             debugprint ("Out of questions")
  202.             self.forward.set_sensitive (False)
  203.             self.close.show ()
  204.             self.cancel.hide ()
  205.         else:
  206.             can = self._can_click_forward (self.questions[page])
  207.             debugprint ("Page %d: can click forward? %s" % (page, can))
  208.             self.forward.set_sensitive (can)
  209.             self.close.hide ()
  210.             self.cancel.show ()
  211.  
  212.     def _on_back_clicked (self, widget):
  213.         self.busy ()
  214.         self.moving_backwards = True
  215.         try:
  216.             self.questions[self.current_page].disconnect_signals ()
  217.         except:
  218.             self._report_traceback ()
  219.  
  220.         self.current_page -= 1
  221.         question = self.questions[self.current_page]
  222.         while not self._display (question):
  223.             # Skip this one.            
  224.             debugprint ("Page %d: skip" % (self.current_page))
  225.             self.current_page -= 1
  226.             question = self.questions[self.current_page]
  227.  
  228.         self.ntbk.set_current_page (self.current_page)
  229.         answers = {}
  230.         for i in range (self.current_page):
  231.             answers.update (self.question_answers[i])
  232.         self.answers = answers
  233.  
  234.         try:
  235.             self.questions[self.current_page].\
  236.                 connect_signals (self._set_back_forward_buttons)
  237.         except:
  238.             self._report_traceback ()
  239.  
  240.         self.moving_backwards = False
  241.         self.ready ()
  242.  
  243.     def _on_forward_clicked (self, widget):
  244.         self.busy ()
  245.         answer_dict = self._collect_answer (self.questions[self.current_page])
  246.         self.question_answers[self.current_page] = answer_dict
  247.         self.answers.update (answer_dict)
  248.  
  249.         try:
  250.             self.questions[self.current_page].disconnect_signals ()
  251.         except:
  252.             self._report_traceback ()
  253.  
  254.         self.current_page += 1
  255.         question = self.questions[self.current_page]
  256.         while not self._display (question):
  257.             # Skip this one, but collect its answers.
  258.             answer_dict = self._collect_answer (question)
  259.             self.question_answers[self.current_page] = answer_dict
  260.             self.answers.update (answer_dict)
  261.             debugprint ("Page %d: skip" % (self.current_page))
  262.             self.current_page += 1
  263.             question = self.questions[self.current_page]
  264.  
  265.         self.ntbk.set_current_page (self.current_page)
  266.         try:
  267.             question.connect_signals (self._set_back_forward_buttons)
  268.         except:
  269.             self._report_traceback ()
  270.  
  271.         self.ready ()
  272.         if get_debugging ():
  273.             self._dump_answers ()
  274.  
  275.     def _dump_answers (self):
  276.         debugprint (self.answers_as_text ())
  277.  
  278.     def _report_traceback (self):
  279.         print "Traceback:"
  280.         (type, value, tb) = sys.exc_info ()
  281.         tblast = traceback.extract_tb (tb, limit=None)
  282.         if len (tblast):
  283.             tblast = tblast[:len (tblast) - 1]
  284.         extxt = traceback.format_exception_only (type, value)
  285.         for line in traceback.format_tb(tb):
  286.             print line.strip ()
  287.         print extxt[0].strip ()
  288.  
  289.     def _display (self, question):
  290.         result = False
  291.         self._in_module_call = True
  292.         try:
  293.             result = question.display ()
  294.         except:
  295.             self._report_traceback ()
  296.  
  297.         self._in_module_call = False
  298.         question.displayed = result
  299.         return result
  300.  
  301.     def _can_click_forward (self, question):
  302.         try:
  303.             return question.can_click_forward ()
  304.         except:
  305.             self._report_traceback ()
  306.             return True
  307.  
  308.     def _collect_answer (self, question):
  309.         answer = {}
  310.         self._in_module_call = True
  311.         try:
  312.             answer = question.collect_answer ()
  313.         except:
  314.             self._report_traceback ()
  315.  
  316.         self._in_module_call = False
  317.         return answer
  318.  
  319. QUESTIONS = ["Welcome",
  320.              "SchedulerNotRunning",
  321.              "CheckLocalServerPublishing",
  322.              "ChoosePrinter",
  323.              "CheckPrinterSanity",
  324.              "CheckPPDSanity",
  325.  
  326.              "LocalOrRemote",
  327.              "DeviceListed",
  328.              "CheckUSBPermissions",
  329.  
  330.              "RemoteAddress",
  331.              "CheckNetworkServerSanity",
  332.              "ChooseNetworkPrinter",
  333.  
  334.              "NetworkCUPSPrinterShared",
  335.  
  336.              "QueueNotEnabled",
  337.              "QueueRejectingJobs",
  338.              "PrinterStateReasons",
  339.  
  340.              "ServerFirewalled",
  341.              "ErrorLogCheckpoint",
  342.              "PrintTestPage",
  343.              "ErrorLogFetch",
  344.              "PrinterStateReasons",
  345.              "ErrorLogParse",
  346.              "Locale",
  347.              "Shrug"]
  348.  
  349. def run (quitfn=None, parent=None):
  350.     troubleshooter = Troubleshooter (quitfn, parent=parent)
  351.     modules_imported = []
  352.     for module in QUESTIONS:
  353.         try:
  354.             if not module in modules_imported:
  355.                 exec ("from %s import %s" % (module, module))
  356.                 modules_imported.append (module)
  357.  
  358.             exec ("%s (troubleshooter)" % module)
  359.         except:
  360.             troubleshooter._report_traceback ()
  361.     return troubleshooter
  362.  
  363. if __name__ == "__main__":
  364.     import sys, getopt
  365.     try:
  366.         opts, args = getopt.gnu_getopt (sys.argv[1:], '',
  367.                                         ['debug'])
  368.         for opt, optarg in opts:
  369.             if opt == '--debug':
  370.                 set_debugging (True)
  371.     except getopt.GetoptError:
  372.         pass
  373.     gtk.gdk.threads_init()
  374.     run (gtk.main_quit)
  375.     gtk.gdk.threads_enter ()
  376.     gtk.main ()
  377.     gtk.gdk.threads_leave ()
  378.